package ua.kharkov.khpi.tarasenko.bach.core.user;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;

import ua.kharkov.khpi.tarasenko.bach.core.item.ItemBean;

/**
 * Shopping cart entity. Stores in user's session
 * 
 * @author oleksandr
 *
 */
public class ShoppingCart implements Serializable {
	private static final long serialVersionUID = 4987479333205298828L;
	private static final Logger log = Logger.getLogger(ShoppingCart.class);

	/**
	 * Key - itemDTO.
	 * 
	 * Mapped values - quantity of the item.
	 */
	private Map<ItemBean, Integer> cart = new HashMap<ItemBean, Integer>();
	private int itemsInCart = 0;
	private double totalPrice = 0;

	public int getItemsInCart() {
		return itemsInCart;
	}

	public void setItemsInCart(int itemsInCart) {
		this.itemsInCart = itemsInCart;
	}

	/**
	 * Adds new item to shopping cart. If it is already in cart, it will be
	 * removed before adding.
	 * 
	 * @param id
	 *            - itemDTO to add.
	 * @param quantity
	 *            - quantity of items.
	 */
	public void addItem(ItemBean item, int quantity) {
		if ((item == null) && (quantity < 1)) {
			if (log.isDebugEnabled()) {
				log.debug("Item cant be null and quantity can't be less then 1.\n"
						+ "item = " + item + "\nQuantity = " + quantity);
			}
			return;
		}
		if (cart.containsKey(item)) {
			removeItem(item, quantity);
		}
		cart.put(item, quantity);
		itemsInCart = itemsInCart + quantity;
	}

	/**
	 * Removes all items in cart with specific id.
	 * 
	 * @param id
	 *            - itemDTO to remove.
	 * @param quantity
	 *            - number of this item in the cart.
	 */
	public void removeItem(ItemBean item, int quantity) {
		if (item == null) {
			if (log.isDebugEnabled()) {
				log.debug("ItemDTO can't be null.");
			}
			return;
		}
		cart.remove(item);
		itemsInCart = itemsInCart - quantity;
	}

	/**
	 * Removes all items in cart with specific id.
	 * 
	 * @param id
	 *            - item's id to remove.
	 */
	public void removeItem(ItemBean item) {
		if (item == null) {
			if (log.isDebugEnabled()) {
				log.debug("ItemDTO can't be null.");
			}
			return;
		}
		int quantity = cart.get(item);
		itemsInCart = itemsInCart - quantity;
		cart.remove(item);
	}

	/**
	 * Calculates total amount to pay.
	 * 
	 */
	public void calculateTotal() {
		double total = 0;
		for (Map.Entry<ItemBean, Integer> entry : cart.entrySet()) {
			total += entry.getKey().getPrice() * entry.getValue();
		}
		totalPrice = total;
	}

	/**
	 * Returns string with id of items to buy.
	 * 
	 * @return items' ids.
	 */
	public String getItemsIds(){
		StringBuilder builder = new StringBuilder();
		for (ItemBean itemBean : cart.keySet()) {
			builder.append(itemBean.getId());
			builder.append(" ");
		}
		return builder.toString();
	}
	
	/**
	 * Returns String with quantities of items to buy.
	 * 
	 * @return items' quantities.
	 */
	public String getItemsQuantities() {
		StringBuilder builder = new StringBuilder();
		for (int quantity : cart.values()) {
			builder.append(quantity);
			builder.append(" ");
		}
		return builder.toString();
	}
	
	public Map<ItemBean, Integer> getCart() {
		return cart;
	}

	public void setCart(Map<ItemBean, Integer> cart) {
		this.cart = cart;
	}

	public double getTotalPrice() {
		return totalPrice;
	}

	public void setTotalPrice(double totalPrice) {
		this.totalPrice = totalPrice;
	}

	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append("Items in cart: ");
		builder.append(getItemsInCart());
		builder.append("\n");
		for (ItemBean item : getCart().keySet()) {
			builder.append(item);
			builder.append("\n");
			builder.append("Quantity: ");
			builder.append(getCart().get(item));
			builder.append("\n");
		}
		builder.append("\n");
		builder.append("Total price: ");
		builder.append(totalPrice);
		builder.append("\n");
		return builder.toString();
	}
}
